package com.zjcode.cdcer.service.impl;

import com.chinatechstar.component.commons.enums.SequenceTypeEnum;
import com.chinatechstar.component.commons.utils.DateUtil;
import com.zjcode.cdcer.mapper.SequenceMapper;
import com.zjcode.cdcer.model.CityEntity;
import com.zjcode.cdcer.model.SequenceEntity;
import com.zjcode.cdcer.service.TkmSysOrgService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SequenceService {

    @Autowired
    private SequenceMapper sequenceMapper;
    @Autowired
    private TkmSysOrgService tkmSysOrgService;


    private SequenceEntity getSequenceEntityByCode(String code) {
        SequenceEntity sequenceByCode = sequenceMapper.getSequenceByCode(code);
        if (sequenceByCode == null) {
            sequenceByCode = new SequenceEntity();
            sequenceByCode.setName(code);
            sequenceByCode.setCode(code);
            sequenceByCode.setFormat("yyMMdd");
            sequenceMapper.insert(sequenceByCode);
            sequenceByCode.setUpdateTime(new Date());
        }
        return sequenceByCode;
    }


    private String getFormat(SequenceEntity sequence) {
        return "MMdd";
    }
    public Integer getSequenceNumByCode(String code) {
        SequenceEntity sequenceByCode = getSequenceEntityByCode(code);
        String format = getFormat(sequenceByCode);

        Date nowData = new Date();
        if (!StringUtils.hasText(format)) {
            Integer num = sequenceByCode.getCurrentNum() + 1;
            sequenceMapper.increaseCurrentNum(num, code);
            return num;
        }
        String sqlDataStr = DateUtil.dateFormat(sequenceByCode.getUpdateTime(), format);
        String nowDateStr = DateUtil.dateFormat(nowData, format);

        Integer num;
        if (sqlDataStr.equals(nowDateStr)) {
            num = sequenceByCode.getCurrentNum() + 1;
        } else {
            num = 1;
        }
        sequenceMapper.increaseCurrentNum(num, code);
        return num;
    }

    public String getSequenceByCode(String code) {
        SequenceEntity sequenceByCode = getSequenceEntityByCode(code);
        String format = getFormat(sequenceByCode);

        Date nowData = new Date();
        if (!StringUtils.hasText(format)) {
            String res = code;
            res += "" + DateUtil.dataToStr(nowData, format);
            Integer num = sequenceByCode.getCurrentNum() + 1;
            res += "" + exChangeCurrentNum(num);
            sequenceMapper.increaseCurrentNum(num, code);
            return res;
        }
        String sqlDataStr = DateUtil.dateFormat(sequenceByCode.getUpdateTime(), format);
        String nowDateStr = DateUtil.dateFormat(nowData, format);

        String configFormat = sequenceByCode.getFormat();
        Integer num;
        String res = code;
        res +=  DateUtil.dataToStr(nowData, configFormat);
//        if (sqlDataStr.equals(nowDateStr)) {
            num = sequenceByCode.getCurrentNum() + 1;
//        } else {
//            num = 1;
//        }
        res +=  exChangeCurrentNum(num);
        sequenceMapper.increaseCurrentNum(num, code);
        return res;

    }

    public String exChangeCurrentNum(int cnum) {
        String s = String.valueOf(cnum);
        int i = s.length();
        switch (i) {
            case 1:
                return "000" + s;
            case 2:
                return "00" + s;
            case 3:
                return "0" + s;
            case 4:
                return s;
        }
        return null;
    }


    public List<CityEntity> getCity(String level, String parentCode) {
        String key = level + "-" + parentCode;

        List<CityEntity> cityEntityList;
        switch (level) {
            case "1":
                cityEntityList = sequenceMapper.getProvincesInfo(parentCode);
                break;
            case "2":
                cityEntityList = sequenceMapper.getCityInfo(parentCode);
                break;
            case "3":
                cityEntityList = sequenceMapper.getAreaInfo(parentCode);
                break;
            case "4":
                cityEntityList = sequenceMapper.getStreetInfo(parentCode);
                break;
            case "5":
                cityEntityList = sequenceMapper.getVillageInfo(parentCode);
                break;
            default:
                throw new RuntimeException("参数错误");
        }
        return cityEntityList;
    }
    public CityEntity getProvincesInfoByName(String parentCode, String name){
        List<CityEntity> provincesInfoByName = sequenceMapper.getProvincesInfoByName(parentCode, name);
        if (provincesInfoByName.size()>0){
            return provincesInfoByName.get(0);
        }else {
            return null;
        }
    }
    public CityEntity getCityInfoByName( String parentCode, String name){
        List<CityEntity> getCityInfoByName = sequenceMapper.getCityInfoByName(parentCode, name);
        if (getCityInfoByName.size()>0){
            return getCityInfoByName.get(0);
        }else {
            return null;
        }
    }
    public CityEntity getAreaInfoByName(String parentCode, String name){
        List<CityEntity> getAreaInfoByName = sequenceMapper.getAreaInfoByName(parentCode, name);
        if (getAreaInfoByName.size()>0){
            return getAreaInfoByName.get(0);
        }else {
            return null;
        }
    }
    public CityEntity getStreetInfoByName( String parentCode,String name){
        List<CityEntity> getStreetInfoByName = sequenceMapper.getStreetInfoByName(parentCode, name);
        if (getStreetInfoByName.size()>0){
            return getStreetInfoByName.get(0);
        }else {
            return null;
        }
    }
    public CityEntity getVillageInfoByName( String parentCode, String name){
        List<CityEntity> getVillageInfoByName = sequenceMapper.getVillageInfoByName(parentCode, name);
        if (getVillageInfoByName.size()>0){
            return getVillageInfoByName.get(0);
        }else {
            return null;
        }
    }

    /**
     * 获取级联地址
     * @return
     */
    public List<CityEntity> getAllCity(){
        String key = "ALL_CITY_LIST";
        //1.先查询redis
        //2.redis不存在查询数据库
        //将数据全部查询，根据code进行处理
        List<CityEntity> allProvincesInfo = sequenceMapper.getAllProvincesInfo();
        List<CityEntity> allCityInfo = sequenceMapper.getAllCityInfo();
        List<CityEntity> allAreaInfo = sequenceMapper.getAllAreaInfo();
//        List<CityEntityVO> allStreetInfo = sequenceMapper.getAllStreetInfo();
//        List<CityEntityVO> allVillageInfo = sequenceMapper.getAllVillageInfo();
        //先对村级处理
//        Map<String, List<CityEntityVO>> villageInfocollect = allVillageInfo.stream()
//                .collect(Collectors.groupingBy(CityEntity::getStreetCode));
        //村级放入上级的children
//        allStreetInfo.forEach(e->e.setChildrenCity(villageInfocollect.get(e.getCode())));
        //街道处理
//        Map<String, List<CityEntityVO>> streetInfocollect = allStreetInfo.stream()
//                .collect(Collectors.groupingBy(CityEntity::getAreaCode));
//        allAreaInfo.forEach(e->e.setChildrenCity(streetInfocollect.get(e.getCode())));
        //区域处理
        Map<String, List<CityEntity>> areaInfocollect = allAreaInfo.stream()
                .collect(Collectors.groupingBy(CityEntity::getCityCode));
        allCityInfo.forEach(e->e.setChildren(areaInfocollect.get(e.getCode())));
        //市处理
        Map<String, List<CityEntity>> cityInfocollect = allCityInfo.stream()
                .collect(Collectors.groupingBy(CityEntity::getProvinceCode));
        allProvincesInfo.forEach(e->e.setChildren(cityInfocollect.get(e.getCode())));
        return allProvincesInfo;
    }

    public List<CityEntity> getCitys(String[] code) {
        List<String> codes = Arrays.asList(code);
        List<CityEntity> res= getAllCity();
        CityEntity cityEntity=null;
        //如果层级于3
        if (codes!=null&&codes.size()>0){
            if (codes.size()<=2){
                return res;
            }else {
                for (int i = 2; i < codes.size(); i++) {
                    //递归查询
                    //获取到
                    cityEntity=getCityTemp(res,codes,i+1);
                   if (i==2) {
                       cityEntity.setChildren(sequenceMapper.getStreetInfo(cityEntity.getCode()));
                   }
                    if (i==3) {
                        cityEntity.setChildren(sequenceMapper.getVillageInfo(cityEntity.getCode()));
                    }
                }
            }
        }
        return res;
    }
    //递归查找
    private CityEntity getCityTemp(List<CityEntity> cityEntities,List<String> codes ,int i){
        //将list转map
        CityEntity temp=null;
        List<CityEntity> tempList=cityEntities;
        for (int j = 0; j < i; j++) {
            int finalJ = j;
            Optional<CityEntity> first = tempList.stream().filter(e -> {
                return e.getCode().equals(codes.get(finalJ));
            }).findFirst();
            temp =first.get();
            if (temp.getChildren()!=null&&temp.getChildren().size()>0){
                tempList=temp.getChildren();
            }else {
                break;
            }
        }
        return temp;


    }

    public String getAddressStr(List<String> code){
        StringBuilder res =new StringBuilder("");
        if (code!=null&&code.size()>0){
            for (int i = 0; i < code.size(); i++) {
                switch (i) {
                    case 0:
                        res.append(sequenceMapper.getProvincesInfoNameByCode(code.get(i)));
                        break;
                    case 1:
                        res.append(sequenceMapper.getAllCityInfoNameByCode(code.get(i)));
                        break;
                    case 2:
                        res.append(sequenceMapper.getAllAreaInfoNameByCode(code.get(i)));
                        break;
                    case 3:
                        res.append(sequenceMapper.getAllStreetInfoNameByCode(code.get(i)));
                        break;
                    case 4:
                        res.append(sequenceMapper.getAllVillageInfoNameByCode(code.get(i)));
                        break;
                    default:
                        throw new RuntimeException("参数错误");
                }
            }
            return res.toString();

        }
        
        return "";
    }

    public List<CityEntity> getBindVillagesList(String areaCode) {
        // 因省疾控不存在区县，传入的值是市编号（如：安徽省疾控中心的市编号“340100”）；其他情况，传入的是区县code
        String substring = areaCode.substring(areaCode.length() - 2);
        List<CityEntity> infos =new ArrayList<>();
        if (Objects.equals("00",substring)) {
            String cityCode = areaCode.substring(0, 4);
            // 1、查市级下的区县列表
            infos = sequenceMapper.getAreaInfo(cityCode);
            // 2、查区县下的所有镇列表
            List<CityEntity> streets =sequenceMapper.getStreets(cityCode);
            Map<String, List<CityEntity>> streetsGroup = streets.stream().collect(Collectors.groupingBy(CityEntity::getAreaCode));
            // 3、查镇下的所有村列表
            List<CityEntity> villages =sequenceMapper.getVillages(cityCode);
            Map<String, List<CityEntity>> villagesGroup = villages.stream().collect(Collectors.groupingBy(CityEntity::getStreetCode));
            infos.forEach(item->{
                List<CityEntity> cityEntities = streetsGroup.get(item.getCode());
                if (!CollectionUtils.isEmpty(cityEntities)) {
                    cityEntities.forEach(each->{
                        each.setChildren(villagesGroup.get(each.getCode()));
                    });
                }
                item.setChildren(cityEntities);
            });
            return infos;
        }
        // 1、查区县下的所有镇列表
        infos = sequenceMapper.getStreetInfo(areaCode);
        // 2、查镇下的所有村列表
        List<CityEntity> villages =sequenceMapper.getVillages(areaCode);
        Map<String, List<CityEntity>> villagesGroup = villages.stream().collect(Collectors.groupingBy(CityEntity::getStreetCode));
        infos.forEach(item->{
            item.setChildren(villagesGroup.get(item.getCode()));
        });
        return infos;
    }

    public List<CityEntity> getVillagesByCodes(List<String> villageCodes) {
        return sequenceMapper.getVillagesByCodes(villageCodes);
    }
}
